<template>
    <div class="container">
        <el-form label-width="120px" :model="dataForm" class="form">
            <el-form-item label="是否创建路由">
                <el-switch v-model="dataForm.isCreateRoute" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
            </el-form-item>
            <el-form-item label="页面名称" v-if="dataForm.isCreateRoute">
                <el-input v-model="dataForm.title"></el-input>
            </el-form-item>
            <el-form-item :label="dataForm.isCreateRoute ? '路由名称' : '文件夹名称'">
                <div style="display: flex">
                    <el-input v-model="dataForm.path" style="margin-right: 10px"></el-input>
                    <el-button type="primary" @click="randomPath">随机 path</el-button>
                </div>
            </el-form-item>
            <el-form-item label="菜单图标" v-if="dataForm.isCreateRoute">
                <el-input v-model="dataForm.icon"></el-input>
            </el-form-item>
            <el-form-item label="列表接口">
                <div style="display: flex">
                    <el-input v-model="dataForm.listUrl"></el-input>
                    <el-select v-model="dataForm.listMethod" placeholder="请选择请求类型">
                        <el-option v-for="(item, index) in methodList" :key="index" :label="item" :value="item"></el-option>
                    </el-select>
                </div>
            </el-form-item>
            <el-form-item label="删除接口">
            <div style="display: flex">
                <el-input v-model="dataForm.delUrl"></el-input>
                <el-select v-model="dataForm.delMethod" placeholder="请选择请求类型">
                    <el-option v-for="(item, index) in methodList" :key="index" :label="item" :value="item"></el-option>
                </el-select>
            </div>
            </el-form-item>
            <el-form-item label="是否配置编辑框">
                <el-switch v-model="dataForm.isEdit" active-color="#13ce66" inactive-color="#ff4949"></el-switch>
            </el-form-item>
            <el-form-item label="详情接口" v-if="dataForm.isEdit">
                <div style="display: flex">
                    <el-input v-model="dataForm.infoUrl"></el-input><el-select v-model="dataForm.infoMethod" placeholder="请选择请求类型">
                        <el-option v-for="(item, index) in methodList" :key="index" :label="item" :value="item"></el-option>
                    </el-select>
                </div>
            </el-form-item>
            <el-form-item label="新增接口" v-if="dataForm.isEdit">
                <div style="display: flex">
                    <el-input v-model="dataForm.addUrl"></el-input>
                    <el-select v-model="dataForm.addMethod" placeholder="请选择请求类型">
                        <el-option v-for="(item, index) in methodList" :key="index" :label="item" :value="item"></el-option>
                    </el-select>
                </div>
            </el-form-item>
            <el-form-item label="编辑接口" v-if="dataForm.isEdit">
                <div style="display: flex">
                    <el-input v-model="dataForm.editUrl"></el-input>
                    <el-select v-model="dataForm.editMethod" placeholder="请选择请求类型">
                        <el-option v-for="(item, index) in methodList" :key="index" :label="item" :value="item"></el-option>
                    </el-select>
                </div>
            </el-form-item>
            
            <el-form-item>
                <div style="display: flex; align-items: flex-start">
                    <el-upload class="upload-demo" :on-change="handleChange" :file-list="fileList" action="" :auto-upload="false" :multiple="false" list-type="json" :limit="1">
                    <el-button>上传表字段</el-button>
                    </el-upload>
                    <el-button type="text" style="margin-left: 10px" @click="downloadTemplate">下载模板</el-button>
                </div>
            </el-form-item>

            <el-form-item>
                <el-button type="primary" @click="submit('codeView')">编辑代码</el-button>
                <el-button type="primary" v-if="browserType === 'Edge'" @click="submit('createPage')">创建新页面</el-button>
                <el-button type="primary" v-if="browserType === 'Edge'" @click="createFolder(blankContent)">创建空页面</el-button>
            </el-form-item>
        </el-form>
        <CodeView ref="codeView" />
    </div>
</template>

<script>
import IndexTemplate from './utils/indexTemplate'
import EditTemplate from './utils/editTemplate'
import Template from './utils/basics'
import { JSON_TEMPLATE, EDIT_TEMPLATE, INDEX_TEMPLATE, PAGECONFIG_TEMPLATE } from './utils/const'
import CodeView from "./components/codeView.vue"

export default {
    components: { CodeView },
    data() {
        return {
            browserType: "",
            blankContent: `<template> <div style="font-size: 20px;">待开发...</div> </template>`,
            dataForm: {
                path: "",
                title: "新建页面",
                hidden: false,
                icon: "user",
                listMethod: "GET",
                delMethod: "DELETE",
                editMethod: "PUT",
                addMethod: "POST",
                infoMethod: "GET",
                listUrl: "/vue-admin-template/table/list",
                delUrl: "/vue-admin-template/table/del",
                editUrl: "/vue-admin-template/table/edit",
                addUrl: "/vue-admin-template/table/add",
                infoUrl: "/vue-admin-template/table/get",
                isEdit: true,
                isCreateRoute: true,
            },
            methodList: ["GET", "POST", "PUT", "DELETE"],
            tableFields: [],
            fileList: [],
        }
    },
    mounted() {
        this.randomPath();
        this.browserType = this.getBrowserInfo(); // 获取浏览器型号
        this.clearCode()
    },
    methods: {
        clearCode() {
            // 重置 vuex 缓存的代码
            this.$store.commit("CODE_SETTING", { key: 'indexCode', value: '' })
            this.$store.commit("CODE_SETTING", { key: 'editCode', value: '' })
            this.$store.commit("CODE_SETTING", { key: 'pageConfig', value: '' })
        },
        // 获取浏览器型号
        getBrowserInfo() {
            const userAgent = navigator.userAgent.toLowerCase();
            
            let browserType = ""
            if (userAgent.indexOf("edg") > -1) {
                browserType = "Edge"
            } else if (userAgent.indexOf("chrome") > -1) {
                browserType = "Chrome"
            } else {
                browserType = "Unknown"
            }
            return browserType
        },
        // 随机 path
        randomPath() {
            const generateRandomString = (length) => {
                const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
                let result = ""
    
                for (let i = 0; i < length; i++) {
                    const randomIndex = Math.floor(Math.random() * characters.length)
                    result += characters[randomIndex]
                }

                return result
            };

            this.dataForm.path = generateRandomString(10);
        },
        handleChange(file, fileList) {
            this.fileList = fileList;
            this.clearCode()
        },
        parseJsonFile(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader()
                reader.onload = function (event) {
                    try {
                        const jsonData = JSON.parse(event.target.result)
                        resolve(jsonData);
                    } catch (error) {
                        reject("解析 JSON 时出错: " + error.message)
                    }
                }
                reader.onerror = function (event) {
                    reject("文件读取错误: " + event.target.error.message)
                }
                reader.readAsText(file)
            })
        },
        openCodeView(row) {
            this.$refs.codeView.init(row);
        },
        submit(type) {
            this.parseJsonFile(this.fileList[0].raw).then((jsonData) => {
                const indexCode = this.$store.state.code.indexCode || new IndexTemplate().setParams({
                    listUrl: this.dataForm.listUrl,
                    listMethod: this.dataForm.listMethod,
                    delUrl: this.dataForm.delUrl,
                    delMethod: this.dataForm.delMethod
                }).setEditComponent(this.dataForm.isEdit).setFields(jsonData).render(INDEX_TEMPLATE)

                const editCode = this.$store.state.code.editCode || new EditTemplate().setParams({
                    infoUrl: this.dataForm.infoUrl,
                    infoMethod: this.dataForm.infoMethod,
                    addUrl: this.dataForm.addUrl,
                    addMethod: this.dataForm.addMethod,
                    editUrl: this.dataForm.editUrl,
                    editMethod: this.dataForm.editMethod,
                }).setFields(jsonData).render(EDIT_TEMPLATE, this.dataForm.isEdit)

                const pageConfig = this.$store.state.code.pageConfig || new Template().setParams({
                    hidden: this.dataForm.hidden,
                    title: this.dataForm.title,
                    icon: this.dataForm.icon,
                }).render(PAGECONFIG_TEMPLATE, this.dataForm.isCreateRoute)

                return {
                    codeView: () => this.openCodeView({ indexCode, editCode, pageConfig }),
                    createPage: () => this.createFolder({ indexCode, editCode, pageConfig }),
                }[type](indexCode, editCode, pageConfig)
            }).catch((error) => {
                alert(error);
            });
        },
        downloadTemplate() {
            // 将 JSON 对象转换为字符串
            const jsonString = JSON.stringify(JSON_TEMPLATE, null, 2); // 格式化 JSON 字符串
            // 创建一个 Blob 对象
            const blob = new Blob([jsonString], { type: "application/json" });
            // 创建一个 URL 对象
            const url = URL.createObjectURL(blob);
            // 创建一个链接元素
            const a = document.createElement("a");
            a.href = url;
            a.download = "JSON_TEMPLATE.json"; // 指定下载的文件名
            // 触发下载
            document.body.appendChild(a); // 将链接添加到文档中
            a.click(); // 自动点击链接
            document.body.removeChild(a); // 下载后移除链接
            // 释放 URL 对象
            URL.revokeObjectURL(url);
        },
        // 创建文件夹
        async createFolder({indexCode, editCode, pageConfig}) {
            try {
                // 显示目录选择对话框，让用户选择一个目录
                const directoryHandle = await window.showDirectoryPicker();
                // 创建一个新的文件夹
                const newFolderHandle = await directoryHandle.getDirectoryHandle(
                    this.dataForm.path,
                    { create: true }
                );
                // 创建一个新的 .vue 文件
                const vueFileHandle = await newFolderHandle.getFileHandle("index.vue", {
                    create: true,
                });
                const vueWritable = await vueFileHandle.createWritable()
                await vueWritable.write(indexCode)
                await vueWritable.close()

                if(this.dataForm.isEdit && editCode) {
                    const formFileHandle = await newFolderHandle.getFileHandle("form.vue", {
                        create: true,
                    });
                    const formWritable = await formFileHandle.createWritable()
                    await formWritable.write(editCode)
                    await formWritable.close()
                }

                if(!this.dataForm.isCreateRoute) return
                // 创建一个新的 .js 文件
                const jsFileHandle = await newFolderHandle.getFileHandle("pageConfig.js",
                    { create: true }
                );
                const jsWritable = await jsFileHandle.createWritable()
                await jsWritable.write(pageConfig)
                await jsWritable.close()
            } catch (error) {
                console.error("创建文件夹或文件时出错:", error)
            }
        }
    }
}

</script>

<style scoped lang="scss">
.container {
  .form {
    width: 500px;
    margin: 0 auto;
    margin-top: 20px;
  }
}
</style>